"""
家庭 | 业务层 基类
"""

from biz.base_biz import ValidatorBase
from my_typing import *
from service.base import (
    ServiceBase,
    TService,
)
from utils.data_utils.special import ObjectIdStr
from utils.exception_utils import BusinessError


class FamilyValidatorBase(ValidatorBase):
    """ 家庭 | 校验器 | 基类 """

    cited_model_service: type[TService] = ServiceBase
    """ 被引用的模型 | 数据层 """

    # -------------------- is_xxx --------------------
    @classmethod
    def is_exist_name(
        cls,
        name: str,
        user_id: ObjectIdStr,
        home_id: ObjectIdStr | None = None,
    ) -> bool:
        """
        名称 是否已存在

        1. 仅校验当前用户的数据
        2. 排除当前更新的数据
        """

        query: dict = {
            "name": name,
            "user_id": user_id,
        }

        if home_id is not None:
            query["id"] = {"$ne": home_id}

        return cls.model_service.exists(query)

    @staticmethod
    def is_valid_alias(
        name: str,
        alias: StrOrNone,
    ) -> bool:
        """ 是否是合法的别名（alias ≠ name） """

        return alias != name

    @classmethod
    def is_cited(cls, home_id: ObjectIdStr) -> bool:
        """ 是否被引用 """

        return cls.cited_model_service.exists({"home_id": home_id})

    # -------------------- validate_xxx --------------------
    @classmethod
    def validate_name_exist(
        cls,
        name: str,
        user_id: ObjectIdStr | None,
    ) -> None:
        """ 校验 | 名称是否存在 """

        if cls.is_exist_name(name, user_id):
            raise BusinessError(f"{cls.model_name}名称 <{name}> 已存在")

    @classmethod
    def validate_alias(
        cls,
        name: str,
        alias: StrOrNone,
    ) -> None:
        """ 校验 | 别名是否合法 """

        if cls.is_valid_alias(name, alias):
            raise BusinessError("别名不能与名称相同")

    @classmethod
    def validate_cited(cls, id: ObjectIdStr) -> None:  # noqa: ignore[built-in name]
        """ 校验 | 是否被引用 """

        if cls.is_cited(id):
            raise BusinessError(f"{cls.model_name} ID <{id}> 正在被使用")
